//-----------------------------------------------------------------------
// <copyright file="AddGroup.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
// </copyright>
// <author>Andy Reeves</author>
// <email>andyr</email>
// <date>2004-03-23</date>
// <summary>Adds an Active Directory group to either a domain group or a local group.</summary>
//-----------------------------------------------------------------------
namespace Microsoft.Sdc.Tasks.ActiveDirectory.Group
{
    using System;
    using Microsoft.Build.Framework;
    using AD = Microsoft.Sdc.Tasks.Configuration.ActiveDirectory;

    /// <summary>
    /// Adds a domain Active Directory Group to a local group.
    /// </summary>
    /// <remarks>
    /// <code><![CDATA[<ActiveDirectory.Group.AddUser 
    ///     GroupName="groupName" 
    ///     Groups="groups" 
    ///     GroupDomain="userDomain" 
    ///     EnsureGroupIsInGroup="ensureGroupIsInGroup" />]]></code>
    /// <para>where:</para>
    /// <para><i>AddGroupName (Required)</i></para>
    /// <para>The name of the group to add to the group.</para>
    /// <para><i>groupName (Required)</i></para>
    /// <para>The groupname to add the user to.</para>
    /// <para><i>AddGroupDomain</i></para>
    /// <para>The domain the group belongs to. If not specified it defaults to the local machine.</para>
    /// <para><i>groupDomain</i></para>
    /// <para>If "true" and the Group is already in the group then no error is thrown. If false, an error will 
    /// be thrown if the specified group is already a member of the specified group. Defaults to false. </para>
    /// </remarks>
    /// <example>
    /// <code><![CDATA[
    /// <Project>
    ///     <Target Name="Test" >
    ///         <ActiveDirectory.Group.AddUser
    ///             GroupName="user1"
    ///             Groups="Domain Administrators"
    ///             GroupDomain="mydomain"
    ///             EnsureGroupIsInGroup="true" />
    ///     </Target>
    /// </Project>
    /// ]]></code>    
    /// </example>
    public class AddGroup : TaskBase
    {
        private string groupName;
        private string[] groups = new string[0];
        private string groupDomain;
        private bool ensureGroupIsInGroup;

        /// <summary>
        /// If "true" and the Group is already in the group then no error is thrown.
        /// </summary>
        /// <value>Set to "true" to not throw an error if the user is already in the group</value>
        public bool EnsureGroupIsInGroup
        {
            get { return this.ensureGroupIsInGroup; }
            set { this.ensureGroupIsInGroup = value; }
        }

        /// <summary>The name of the group to add to the groups.</summary>
        /// <value>The name of the group.</value>
        [Required]
        public string GroupName
        {
            get { return (this.groupName ?? String.Empty); }
            set { this.groupName = value; }
        }

        /// <summary>The name of the domain that the group belongs to.</summary>
        /// <value>The name of the group.</value>
        [Required]
        public string GroupDomain
        {
            get { return (this.groupDomain ?? String.Empty); }
            set { this.groupDomain = value; }
        }

        /// <summary><para>The groups to add the group to.</para>
        /// </summary>
        /// <value>The name of the groups.</value>
        [Required]
        public string[] Groups
        {
            get { return this.groups; }
            set { this.groups = value; }
        }

        /// <summary>
        /// Performs the action of this task.
        /// </summary>        
        protected override void InternalExecute()
        {
            #region Execute code

            if (!AD.Group.Exists(this.groupName, this.groupDomain))
            {
                throw new TaskException("ActiveDirectory.GroupDoesNotExist", this.groupName);
            }
            else
            {
                AD.Group group;
                group = AD.Group.Load(this.groupName, this.groupDomain);

                // Now loop through all the groups provided and add the user to each of them

                for (int i = 0; i < this.Groups.Length; i++)
                {
                    string localGroup = this.GetGroupName(i);

                    Log.LogMessageFromResources("ActiveDirectory.AddGroupToGroup", this.groupName, localGroup);

                    if (!group.IsInGroup(localGroup))
                    {
                        group.AddToGroup(localGroup);
                    }
                    else
                    {
                        if (!this.ensureGroupIsInGroup)
                        {
                            throw new TaskException("ActiveDirectory.GroupAlreadyLocalGroupMember", this.groupName, localGroup);
                        }
                    }
                }
            }
            #endregion
        }

        private string GetGroupName(int index)
        {
            if (index >= this.Groups.Length)
            {
                return null;
            }
            return this.Groups[index];
        }
    }
}